#include "ViewScene.hpp"
#include "gl.hpp"
#include "glu.hpp"
#include "MeshView.hpp"
#include "MenuEvents.hpp"

boost::signal<void ()> ViewScene::SelectedVertsChanged;
boost::signal<void ()> ViewScene::SelectedMeshChanged;

ViewScene& ViewScene::GetInstance()
{
   static ViewScene i;
   return i;
}
ViewScene::ViewScene()
{
   mSelectionMode = cVERTEX;
   mSelectedMesh = 0;

   
}
void ViewScene::LoadProjection(float aOffsetValue)
{
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   float aspect = mTransform.mWidth / mTransform.mHeight;
   gluPerspective(45,aspect,mTransform.mNearPlane / aOffsetValue, mTransform.mFarPlane / aOffsetValue);
   glMatrixMode(GL_MODELVIEW);
}
void ViewScene::Draw()
{
#ifdef USE_DP
   dp.resize(mTransform.mWidth, mTransform.mHeight);
   dp.Init();
   dp.Begin();
   DrawModels();
   while (dp.NextLayer())
   {
      DrawModels();
   }
   dp.End();
#endif
   DrawModels();
} 

void ViewScene::DrawModels()
{
   for (size_t i = 0; i < mModels.size(); ++i)
   {
      mModels[i]->Draw();
   }
}
void ViewScene::AddMesh(MeshView* aMesh)
{ 
   mModels.push_back(aMesh); 
   MEvents("Mesh Added");
}

int ViewScene::GetMeshIndex(MeshView* aMeshPtr)
{
   for (size_t i = 0; i < mModels.size(); ++i)
   {
      if (mModels[i]==aMeshPtr){return i;}
   }
   return -1;
}

void ViewScene::MoveMesh(MeshView* aMeshPtr,
                         int       aMoveOffset)
{
   int startIndex = GetMeshIndex(aMeshPtr);
   if (startIndex >= 0)
   {
      int finalIndex = startIndex + aMoveOffset;
      if (finalIndex >= 0 && finalIndex < (int)mModels.size())
      {
         std::swap(mModels[startIndex + aMoveOffset], mModels[startIndex]);
      }
   }
}

void ViewScene::SetSelectedMesh(int aIndex)
{
   if (aIndex >= 0 && aIndex < (int)mModels.size())
   {
      if (mSelectedMesh != aIndex)
      {
         mSelectedMesh = aIndex;
         ViewScene::SelectedMeshChanged();
         MEvents("Mesh Selected");
      }
   }
}

void ViewScene::SetSelectedMesh(MeshView* aMeshPtr)
{
   SetSelectedMesh(GetMeshIndex(aMeshPtr)); 
}

MeshView* ViewScene::GetSelectedMesh()
{
   if (mSelectedMesh>=0 && mSelectedMesh < mModels.size())
   {
      return mModels[mSelectedMesh];
   }
   return 0;
}

void ViewScene::Remove(MeshView* aMeshPtr)
{
   int index = GetMeshIndex(aMeshPtr);
   if (index >= 0)
   {
      mModels.erase(mModels.begin() + index);
   }
   if (mSelectedMesh != 0 && mSelectedMesh > int(mModels.size())-1)
   {
      mSelectedMesh = 0;
   }
   MEvents("Mesh Added");
}
